package cn.com.dashihui.seller.service;

import java.util.ArrayList;
import java.util.List;

import com.jfinal.aop.Before;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;

import cn.com.dashihui.seller.common.OrderCode;
import cn.com.dashihui.seller.common.SellerState;
import cn.com.dashihui.seller.common.SellerState.DispatchState;
import cn.com.dashihui.seller.common.SysConfig;
import cn.com.dashihui.seller.common.UserCode;
import cn.com.dashihui.seller.dao.Order;
import cn.com.dashihui.seller.dao.OrderList;
import cn.com.dashihui.seller.dao.OrderRefund;
import cn.com.dashihui.seller.dao.Seller;
import cn.com.dashihui.seller.dao.User;
import cn.com.dashihui.seller.kit.CommonKit;
import cn.com.dashihui.seller.kit.DatetimeKit;
import cn.com.dashihui.seller.kit.DoubleKit;
import cn.com.dashihui.seller.kit.InviteCodeKit;

public class OrderService {
	
	/**
	 * 查询所有未接的订单（((在线支付 and 已支付) or 货到付款) and ((送货上门 and 未发货) or 门店自取)，正常）
	 */
	public List<Order> findNews(int storeid){
		String sql = "SELECT bo.*,0 state FROM t_bus_order bo WHERE bo.storeid=?"
				+ " AND ((bo.payType=? AND bo.payState=?) OR bo.payType=?)"
				+ " AND ((bo.takeType=? AND bo.deliverState=?) OR bo.takeType=?)"
				+ " AND bo.orderState=?"
				+ " AND NOT EXISTS (SELECT 1 FROM t_dict_store_seller_rel WHERE orderNum=bo.orderNum)"
				+ " ORDER BY bo.createDate DESC";
		return Order.me().find(sql,storeid,
				OrderCode.OrderPayType.ON_LINE,OrderCode.OrderPayState.HAD_PAY,OrderCode.OrderPayType.ON_DELIVERY,
				OrderCode.OrderTakeType.DELIVER,OrderCode.OrderDeliverState.NO_DELIVER,OrderCode.OrderTakeType.TAKE_SELF,
				OrderCode.OrderState.NORMAL);
	}

	
	/**
	 * 用户查询各种状态的订单列表
	 */
	public Page<Order> findByPage(int storeid,int userid,int type,int pageNum,int pageSize){
		if(type==1){
			//1：未完成
			String sql = "FROM t_bus_order bo"
					+ " INNER JOIN t_dict_store_seller_rel dssr ON bo.orderNum=dssr.orderNum"
					+ " INNER JOIN t_dict_store_seller dss ON dssr.sellerid=dss.id"
					+ " WHERE dssr.isShow=? AND bo.storeid=? AND dss.id=? AND dssr.state!=?"
					+ " ORDER BY bo.createDate DESC";
			return Order.me().paginate(pageNum, pageSize, "SELECT bo.*,dssr.state,dss.id sellerid,dss.name sellerName ",sql,SellerState.ShowState.SHOW,storeid,userid,SellerState.DispatchState.FINISH);
		}else if(type==2){
			//2：已完成
			String sql = "FROM t_bus_order bo"
					+ " INNER JOIN t_dict_store_seller_rel dssr ON bo.orderNum=dssr.orderNum"
					+ " INNER JOIN t_dict_store_seller dss ON dssr.sellerid=dss.id"
					+ " WHERE dssr.isShow=? AND bo.storeid=? AND dss.id=? AND dssr.state=?"
					+ " ORDER BY bo.createDate DESC";
			return Order.me().paginate(pageNum, pageSize, "SELECT bo.*,dssr.state,dss.id sellerid,dss.name sellerName ",sql,SellerState.ShowState.SHOW,storeid,userid,SellerState.DispatchState.FINISH);
		}
		return null;
	}
	
	/**
	 * 根据订单号查询出订单<br/>
	 * 注：排除配送员隐藏掉的订单
	 */
	public Order getOrderByOrderNum(int storeid,String orderNum){
		String sql = "SELECT"
				+ " bo.*,IFNULL(dssr.state,0) state,dss.id sellerid,dss.name sellerName,dssr.isShow,ds.title storeTitle,ds.address storeAddress"
				+ " FROM t_bus_order bo"
				+ " LEFT JOIN t_dict_store_seller_rel dssr ON bo.orderNum=dssr.orderNum"
				+ " LEFT JOIN t_dict_store_seller dss ON dssr.sellerid=dss.id"
				+ "	LEFT JOIN t_dict_store ds on bo.storeid = ds.id"
				+ " WHERE bo.storeid=? AND bo.orderNum=?";
		return Order.me().findFirst(sql,storeid,orderNum);
	}
	
	/**
	 * 根据订单号查询出订单<br/>
	 * 注：排除配送员隐藏掉的订单
	 */
	public Order getOrderByOrderNum(int storeid,int sellerid,String orderNum){
		String sql = "SELECT"
				+ " bo.*,IFNULL(dssr.state,0) state,dss.id sellerid,dss.name sellerName,dssr.isShow"
				+ " FROM t_bus_order bo"
				+ " INNER JOIN t_dict_store_seller_rel dssr ON bo.orderNum=dssr.orderNum"
				+ " INNER JOIN t_dict_store_seller dss ON dssr.sellerid=dss.id"
				+ " WHERE bo.storeid=? AND dssr.sellerid=? AND bo.orderNum=?";
		return Order.me().findFirst(sql,storeid,sellerid,orderNum);
	}
	
	/**
	 * 根据订单号查询商品列表
	 */
	public List<Record> getGoodsListByOrderNum(String orderNum){
		String sql = "SELECT ol.id,ol.goodsid,ol.name,ol.price,ol.thumb,ol.spec,ol.count,ol.amount,"
				+ " IFNULL(bo.payState,0) payState,IFNULL(bo.payType,0) payType,"
				+ " IFNULL(ord.state,0) refundState,IFNULL(ord.type,0) refundType"
				+ " FROM t_bus_order_list ol"
				+ " LEFT JOIN t_bus_order_refund ord ON ol.id = ord.orderListid AND ol.orderNum = ord.orderNum"
				+ " LEFT JOIN t_bus_order bo ON ol.orderNum = bo.orderNum"
				+ " WHERE ol.orderNum=?";
		return Db.find(sql, orderNum);
	}
	
	/**
	 * 根据订单号查询商品退款总额和零钱退款总额
	 */
	public List<Record> getRefundListByOrderNum(String orderNum) {
		String sql = "(select IFNULL(SUM(amount),0) amount,orderNum,type FROM t_bus_order_refund WHERE type=2 AND state = 4 AND type != 1 AND orderNum = ?)"
				+ " UNION "
				+ " (select IFNULL(SUM(amount),0) amount,orderNum,type FROM t_bus_order_refund WHERE type=3  AND state = 4 AND type != 1 AND orderNum = ?)";
		return Db.find(sql, orderNum, orderNum);
	}
	
	/**
	 * 查询多个订单的商品列表
	 */
	public void getOrderGoodsList(List<Order> orderList){
		if(orderList!=null){
			//将所有订单的编号取出，以逗号分隔拼接
			String[] orderNumArr = new String[orderList.size()];
			for(int i=0;i<orderList.size();i++){
				orderNumArr[i] = "'"+orderList.get(i).getStr("orderNum")+"'";
			}
			//以订单编号为条件，查询所有订单的所有商品列表，并以订单号排序，方便遍历整理
			List<Record> allGoodsList = Db.find("SELECT"
					+ " ol.orderNum,ol.goodsid,ol.name,ol.price,ol.thumb,ol.spec,ol.count,ol.amount,"
					+ " IFNULL(ord.state,0) refundState,IFNULL(ord.type,0) refundType"
					+ " FROM t_bus_order_list ol"
					+ " LEFT JOIN t_bus_order_refund ord ON ol.id = ord.orderListid AND ol.orderNum = ord.orderNum"
					+ " WHERE ol.orderNum IN ("+CommonKit.join(",", orderNumArr)+") ORDER BY ol.orderNum");
			//遍历所有商品和订单，根据订单号将商品归类给对应的订单对象
			for(Order order : orderList){
				List<Record> goodsList = order.get("goodsList");
				if(goodsList==null){
					goodsList = new ArrayList<Record>();
				}
				for(Record goods : allGoodsList){
					if(order.getStr("orderNum").equals(goods.getStr("orderNum"))){
						goodsList.add(goods);
					}
				}
				order.put("goodsList",goodsList);
			}
		}
	}
	
	/**
	 * 配送员接单
	 */
	@Before(Tx.class)
	public boolean doAccept(Seller seller,Order order){
		int sellerid = seller.getInt("id");
		String orderNum = order.getStr("orderNum");
		if(Db.update("INSERT INTO t_dict_store_seller_rel(sellerid,orderNum,state) VALUES(?,?,?)",sellerid,orderNum,DispatchState.WAIT_PACK)==1){
			//更新订单表，记录配送员ID及打包状态为：已接单
			order.set("sellerid", sellerid).set("packState", OrderCode.OrderPackState.HAD_ACCEPT).update();
			log(orderNum,OrderCode.OrderLogType.ACCEPT,"配送员："+seller.getStr("name"),OrderCode.OrderLogType.ACCEPT_ACTION, "系统已确认，等待商品打包");
			return true;
		}
		return false;
	}
	
	/**
	 * 配送员配货
	 */
	@Before(Tx.class)
	public boolean doPack(Seller seller,Order order){
		int sellerid = seller.getInt("id");
		String orderNum = order.getStr("orderNum");
		if(Db.update("UPDATE t_dict_store_seller_rel SET state=? WHERE sellerid=? AND orderNum=? AND state=?",DispatchState.PACKING,sellerid,orderNum,DispatchState.WAIT_PACK)==1){
			//更新订单表，修改打包状态为：打包中
			order.set("packState", OrderCode.OrderPackState.PACKING).update();
			log(orderNum,OrderCode.OrderLogType.PACK,"配送员："+seller.getStr("name"),OrderCode.OrderLogType.PACK_ACTION, "商品正在打包");
			return true;
		}
		return false;
	}
	
	/**
	 * 配送员配货完成
	 */
	@Before(Tx.class)
	public boolean doPackFinish(Seller seller,Order order){
		int sellerid = seller.getInt("id");
		String orderNum = order.getStr("orderNum");
		if(Db.update("UPDATE t_dict_store_seller_rel SET state=? WHERE sellerid=? AND orderNum=? AND state=?",DispatchState.PACK_FINISH,sellerid,orderNum,DispatchState.PACKING)==1){
			//更新订单表，修改打包状态为：打包完成
			order.set("packState", OrderCode.OrderPackState.PACK_FINISH).update();
			log(orderNum,OrderCode.OrderLogType.PACK_FINISH,"配送员："+seller.getStr("name"),OrderCode.OrderLogType.PACK_FINISH_ACTION, "商品打包完成，正在安排配送");
			return true;
		}
		return false;
	}
	
	/**
	 * 配货完成，待取货
	 */
	@Before(Tx.class)
	public boolean doWait(Seller seller,Order order){
		int sellerid = seller.getInt("id");
		String orderNum = order.getStr("orderNum");
		if(Db.update("UPDATE t_dict_store_seller_rel SET state=? WHERE sellerid=? AND orderNum=? AND state=?",DispatchState.WAIT_GET,sellerid,orderNum,DispatchState.PACK_FINISH)==1){
			log(orderNum,OrderCode.OrderLogType.PACK_FINISH,"配送员："+seller.getStr("name"),OrderCode.OrderLogType.PACK_FINISH_ACTION, "商品打包完成，请在营业时间内上门取货");
			return true;
		}
		return false;
	}
	
	/**
	 * 配货完成，送货
	 */
	@Before(Tx.class)
	public boolean doSend(Seller seller,Order order){
		int sellerid = seller.getInt("id");
		String orderNum = order.getStr("orderNum");
		if(Db.update("UPDATE t_dict_store_seller_rel SET state=? WHERE sellerid=? AND orderNum=? AND state=?",DispatchState.DISPATCHING,sellerid,orderNum,DispatchState.PACK_FINISH)==1){
			//更新订单发货状态为已发货，并记录发货时间
			order.set("deliverState", OrderCode.OrderDeliverState.HAD_DELIVER).set("deliverDate", DatetimeKit.getFormatDate("yyyy-MM-dd HH:mm:ss")).update();
			log(orderNum,OrderCode.OrderLogType.DISPATCH,"配送员："+seller.getStr("name"),OrderCode.OrderLogType.DISPATCH_ACTION, "商品正在配送，请注意保持电话畅通，大实惠配送员【"+seller.getStr("name")+"】，联系电话【"+seller.getStr("tel")+"】");
			return true;
		}
		return false;
	}
	
	/**
	 * 收货或取货
	 */
	@Before(Tx.class)
	public void doFinish(Seller seller,Order order) throws Exception{
		int sellerid = seller.getInt("id");
		String orderNum = order.getStr("orderNum");
		if(order.getInt("takeType")==OrderCode.OrderTakeType.DELIVER){
			if(Db.update("UPDATE t_dict_store_seller_rel SET state=? WHERE sellerid=? AND orderNum=? AND state=?",DispatchState.FINISH,sellerid,orderNum,DispatchState.DISPATCHING)==1){
				//更新订单状态为已完成，并记录完成时间
				order.set("orderState", OrderCode.OrderState.FINISH).set("signDate", DatetimeKit.getFormatDate("yyyy-MM-dd HH:mm:ss")).update();
				log(orderNum,OrderCode.OrderLogType.SIGN,"配送员："+seller.getStr("name"),OrderCode.OrderLogType.SIGN_ACTION,"商品已签收，感谢您在大实惠购物，欢迎再次光临！");
				//根据用户所购买的商品，进行分销处理
				rebate(order);
			}
		}else if(order.getInt("takeType")==OrderCode.OrderTakeType.TAKE_SELF){
			if(Db.update("UPDATE t_dict_store_seller_rel SET state=? WHERE sellerid=? AND orderNum=? AND state=?",DispatchState.FINISH,sellerid,orderNum,DispatchState.WAIT_GET)==1){
				//更新订单状态为已完成，并记录完成时间
				order.set("orderState", OrderCode.OrderState.FINISH).set("signDate", DatetimeKit.getFormatDate("yyyy-MM-dd HH:mm:ss")).update();
				log(orderNum,OrderCode.OrderLogType.GET,"配送员："+seller.getStr("name"),OrderCode.OrderLogType.GET_ACTION,"已取货，感谢您在大实惠购物，欢迎再次光临！");
				//根据用户所购买的商品，进行分销处理
				rebate(order);
			}
		}
	}
	
	private void rebate(Order order) throws Exception{
		String orderNum = order.getStr("orderNum");
		//查询订单商品列表
		List<Record> goodsList = Db.find("SELECT goodsid,amount,isRebate,percent1,percent2,percent3,percent4,percent5 FROM t_bus_order_list WHERE orderNum=?", order.getStr("orderNum"));
		
		//所购开启分销商品总额
		double totalAmount = 0;
		
		//分销日志SQL
		String logSql = "INSERT INTO t_log_rebate(orderNum,goodsid,amount,percent1,money1,percent2,money2,percent3,money3,percent4,money4,percent5,money5) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)";
		
		//分销日志列表1
		List<Object[]> logParams1 = new ArrayList<Object[]>();
		//分销分成1（用户为普通用户，非黄金会员，也没有邀请用户，此时推荐人、DSH、社区享利）
		double[] rebate1 = new double[5];
		
		//分销日志列表2
		List<Object[]> logParams2 = new ArrayList<Object[]>();
		//分销分成2（用户为普通用户，非黄金会员，有邀请用户，此时推荐人、DSH、社区负责人、一级分销享利）
		double[] rebate2 = new double[5];
		
		//分销日志列表3
		List<Object[]> logParams3 = new ArrayList<Object[]>();
		//分销分成3（用户为黄金会员，也没有邀请用户，此时推荐人、DSH、社区负责人、二级分销享利）
		double[] rebate3 = new double[5];
		
		//分销日志列表4
		List<Object[]> logParams4 = new ArrayList<Object[]>();
		//分销分成4（用户为黄金会员，有邀请用户，此时推荐人、DSH、社区负责人、一级分销、二级分销享利）
		double[] rebate4 = new double[5];
		
		//遍历所有商品
		for(Record goods : goodsList){
			if(goods.getInt("isRebate")==1){
				int goodsid = goods.getInt("goodsid");
				//商品总金额
				double amount = goods.getDouble("amount");
				//商品设置“推荐人”返利比例
				double percent1 = DoubleKit.mul(goods.getDouble("percent1"),0.01);
				//商品设置“DSH”返利比例
				double percent2 = DoubleKit.mul(goods.getDouble("percent2"),0.01);
				//商品设置“社区负责人”返利比例
				double percent3 = DoubleKit.mul(goods.getDouble("percent3"),0.01);
				//商品设置“一级分销”返利比例
				double percent4 = DoubleKit.mul(goods.getDouble("percent4"),0.01);
				//商品设置“二级分销”返利比例
				double percent5 = DoubleKit.mul(goods.getDouble("percent5"),0.01);
				//累计本单中所有开启返利的商品的消费金额
				totalAmount = DoubleKit.add(totalAmount, amount);
				//用户为普通用户，非黄金会员，也没有邀请用户，此时推荐人、DSH、社区负责人享利
				rebate1[0] = DoubleKit.add(rebate1[0], DoubleKit.mul(amount,percent1));
				rebate1[1] = DoubleKit.add(rebate1[1], DoubleKit.mul(amount,percent2+percent4+percent5));
				rebate1[2] = DoubleKit.add(rebate1[2], DoubleKit.mul(amount,percent3));
				rebate1[3] = 0;
				rebate1[4] = 0;
				logParams1.add(new Object[]{orderNum,goodsid,amount,percent1,rebate1[0],percent2,rebate1[1],percent3,rebate1[2],percent4,rebate1[3],percent5,rebate1[4]});
				//用户为普通用户，非黄金会员，有邀请用户，此时推荐人、DSH、社区负责人、一级分销享利
				rebate2[0] = DoubleKit.add(rebate1[0], DoubleKit.mul(amount,percent1));
				rebate2[1] = DoubleKit.add(rebate1[1], DoubleKit.mul(amount,percent2+percent5));
				rebate2[2] = DoubleKit.add(rebate1[2], DoubleKit.mul(amount,percent3));
				rebate2[3] = DoubleKit.add(rebate1[3], DoubleKit.mul(amount,percent4));
				rebate2[4] = 0;
				logParams2.add(new Object[]{orderNum,goodsid,amount,percent1,rebate2[0],percent2,rebate2[1],percent3,rebate2[2],percent4,rebate2[3],percent5,rebate2[4]});
				//用户为黄金会员，也没有邀请用户，此时推荐人、DSH、社区负责人、二级分销享利
				rebate3[0] = DoubleKit.add(rebate1[0], DoubleKit.mul(amount,percent1));
				rebate3[1] = DoubleKit.add(rebate1[1], DoubleKit.mul(amount,percent2+percent4));
				rebate3[2] = DoubleKit.add(rebate1[2], DoubleKit.mul(amount,percent3));
				rebate3[3] = 0;
				rebate3[4] = DoubleKit.add(rebate1[4], DoubleKit.mul(amount,percent5));
				logParams3.add(new Object[]{orderNum,goodsid,amount,percent1,rebate3[0],percent2,rebate3[1],percent3,rebate3[2],percent4,rebate3[3],percent5,rebate3[4]});
				//用户为黄金会员，有邀请用户，此时推荐人、DSH、社区负责人、一级分销、二级分销享利
				rebate4[0] = DoubleKit.add(rebate1[0], DoubleKit.mul(amount,percent1));
				rebate4[1] = DoubleKit.add(rebate1[1], DoubleKit.mul(amount,percent2));
				rebate4[2] = DoubleKit.add(rebate1[2], DoubleKit.mul(amount,percent3));
				rebate4[3] = DoubleKit.add(rebate1[3], DoubleKit.mul(amount,percent4));
				rebate4[4] = DoubleKit.add(rebate1[4], DoubleKit.mul(amount,percent5));
				logParams4.add(new Object[]{orderNum,goodsid,amount,percent1,rebate4[0],percent2,rebate4[1],percent3,rebate4[2],percent4,rebate4[3],percent5,rebate4[4]});
			}
		}
		//如果有返利的商品消费金额为0，则不处理
		if(totalAmount==0)return;
		//用户ID
		int userid = order.getInt("userid");
		//查询相应下单的用户信息
		User user = User.me().findById(userid);
		//用户注册邀请人ID
		int inviteUserid = user.getInt("inviteUserid");
		if(user.getInt("level")==UserCode.UserLevel.LEVEL1){
			//查询用户以前购买并签收（在线支付）的有返利的商品所消费的金额（不包括本次消费的订单金额）
			Record history = Db.findFirst("SELECT IFNULL(SUM(amount),0) amount"
					+ " FROM t_bus_order_list bol WHERE isRebate=1 AND EXISTS("
					+ " SELECT 1"
					+ " FROM t_bus_order bo"
					+ " INNER JOIN t_bus_order_log bolog ON bo.orderNum=bolog.orderNum"
					+ " WHERE bolog.type=? AND bo.userid=? AND bo.orderNum=bol.orderNum AND bo.orderNum!=?)",
					OrderCode.OrderLogType.SIGN,userid,orderNum);
			if(history!=null){
				//加上本次所消费的金额
				totalAmount = DoubleKit.add(totalAmount, history.getDouble("amount"));
			}
			//用户为普通会员时
			double level2Line = SysConfig.getLevel2Line();
			if(totalAmount>=level2Line){
				//当本次所购的开启返利的商品的消费总金额达到黄金会员线的时候
				//1.更新用户会员等级为黄金会员，并生成唯一邀请码保存（根据用户ID生成，可逆）
				Db.update("UPDATE t_bus_user SET level=?,inviteCode=? WHERE id=? AND level=?",UserCode.UserLevel.LEVEL2,InviteCodeKit.toSerialCode(userid),userid,UserCode.UserLevel.LEVEL1);
				//2.记录用户会员等级变化日志
				Db.update("INSERT INTO t_bus_user_level_log(userid,fromLevel,toLevel,flag,`describe`,fromOrderNum) VALUES(?,?,?,?,?,?)",userid,UserCode.UserLevel.LEVEL1,UserCode.UserLevel.LEVEL2,UserCode.UserLevelLogFlag.CONSUME,"消费",orderNum);
			}
			if(inviteUserid==0){
				//如果用户注册时没有邀请人，则本次购物所有返利将由推荐人、DSH、社区负责人享利
				//1.记录分销日志1
				Db.batch(logSql, parseParams(logParams1), logParams1.size());
			}else{
				//如果用户注册时有邀请人，则本次购物所有返利将由推荐人、DSH、社区负责人、一级分销享利
				//1.更新一级分销用户的“实惠币金额”
				User inviteUser = User.me().findById(inviteUserid);
				if(inviteUser==null){
					throw new Exception("用户（用户ID："+userid+"）的注册邀请人（用户ID："+inviteUserid+"）找不到！");
				}
				//此处使用行锁定的方式更新，防止并发
				if(Db.update("UPDATE t_bus_user SET money=money+? WHERE id=? AND money=?",rebate2[3],inviteUserid,inviteUser.getDouble("money"))!=1){
					throw new Exception("用户（用户ID："+userid+"）的注册邀请人（用户ID："+inviteUserid+"）更新money时出错！");
				}
				//2.记录一级分销用户的“实惠币金额”变动日志（记录订单号）
				Db.update("INSERT INTO t_bus_user_value_log(userid,amount,type,flag,`describe`,fromUserid,fromOrderNum) VALUES(?,?,?,?,?,?,?)",inviteUserid,rebate2[3],1,UserCode.UserValueLogFlag.CONSUME_UNDER,"下线用户消费",userid,orderNum);
				//3.记录分销日志2
				Db.batch(logSql, parseParams(logParams2), logParams2.size());
			}
		}else if(user.getInt("level")==UserCode.UserLevel.LEVEL2){
			//用户为黄金会员时
			if(inviteUserid==0){
				//如果用户注册时没有邀请人，则本次购物所有返利将由推荐人、DSH、社区负责人、二级分销享利
				//1.更新二级分销用户（即当前用户）的“实惠币金额”
				//此处使用行锁定的方式更新，防止并发
				if(Db.update("UPDATE t_bus_user SET money=money+? WHERE id=? AND money=?",rebate3[4],userid,user.getDouble("money"))!=1){
					throw new Exception("用户（用户ID："+userid+"）更新money时出错！");
				}
				//2.记录二级分销用户（即当前用户）的“实惠币金额”变动日志（记录订单号）
				Db.update("INSERT INTO t_bus_user_value_log(userid,amount,type,flag,`describe`,fromOrderNum) VALUES(?,?,?,?,?,?)",userid,rebate3[4],1,UserCode.UserValueLogFlag.CONSUME_SELF,"消费",orderNum);
				//3.记录分销日志3
				Db.batch(logSql, parseParams(logParams3), logParams3.size());
			}else{
				//如果用户注册时有邀请人，则本次购物所有返利将由推荐人、DSH、社区负责人、一级分销、二级分销享利
				//1.更新一级分销用户和二级分销用户（即当前用户）的“实惠币金额”
				User inviteUser = User.me().findById(inviteUserid);
				if(inviteUser==null){
					throw new Exception("用户（用户ID："+userid+"）的注册邀请人（用户ID："+inviteUserid+"）找不到！");
				}
				//此处使用行锁定的方式更新，防止并发
				if(Db.update("UPDATE t_bus_user SET money=money+? WHERE id=? AND money=?",rebate4[3],inviteUserid,inviteUser.getDouble("money"))!=1){
					throw new Exception("用户（用户ID："+userid+"）的注册邀请人（用户ID："+inviteUserid+"）更新money时出错！");
				}
				if(Db.update("UPDATE t_bus_user SET money=money+? WHERE id=? AND money=?",rebate4[4],userid,user.getDouble("money"))!=1){
					throw new Exception("用户（用户ID："+userid+"）更新money时出错！");
				}
				//2.记录一级分销用户和二级分销用户（即当前用户）的“实惠币金额”变动日志（记录订单号）
				Db.update("INSERT INTO t_bus_user_value_log(userid,amount,type,flag,`describe`,fromUserid,fromOrderNum) VALUES(?,?,?,?,?,?,?)",inviteUserid,rebate4[3],1,UserCode.UserValueLogFlag.CONSUME_UNDER,"下线用户消费",userid,orderNum);
				Db.update("INSERT INTO t_bus_user_value_log(userid,amount,type,flag,`describe`,fromOrderNum) VALUES(?,?,?,?,?,?)",userid,rebate4[4],1,UserCode.UserValueLogFlag.CONSUME_SELF,"消费",orderNum);
				//3.记录分销日志4
				Db.batch(logSql, parseParams(logParams4), logParams4.size());
			}
		}
	}
	
	/**
	 * 将list<object[]>集合转换为object[][]
	 * @param params list<object[]>集合
	 */
	private Object[][] parseParams(List<Object[]> params){
		if(params!=null){
			Object[][] result = new Object[params.size()][];
			for(int index = 0;index<params.size();index++){
				result[index] = params.get(index);
			}
			return result;
		}
		return null;
	}
	
	/**
	 * 记录操作日志
	 */
	private void log(String orderNum, int type, String user, String action, String content){
		Db.update("INSERT INTO t_bus_order_log(orderNum,type,user,action,content) VALUES(?,?,?,?,?)",orderNum,type,user,action,content);
	}
	
	/**
	 * 单个商品退款
	 * @param orderNum 订单号
	 * @param orderListid 要退的订单清单中的商品
	 * @return flag：-1：退款失败，1：退款成功，2：退款成功+订单已取消，3：订单已取消或该商品已存在退款记录，4：剩余可退金额不足
	 */
	@Before(Tx.class)
	public int doSingleRefund(String orderNum, int orderListid, Order order) throws Exception {
		int flag = -1;
		//判断当前商品是否可以退款
		String sqlRefund = "SELECT * FROM t_bus_order_refund bor WHERE state !=? AND orderNum=? AND (bor.type=?) OR (bor.type=? and orderListid=?)";
		List<Record> list = Db.find(sqlRefund,OrderCode.RefundState.VERIFY_FAILED, orderNum, OrderCode.RefundType.CANCEL_ORDER, OrderCode.RefundType.CANCEL_SINGLE, orderListid);
		if(list.size() > 0) {
			flag = 3;
		} else {
			//1.查询本次要退款的商品的小计金额，作为要退的金额
			String sqlOrderList = "SELECT IFNULL(amount,0) amount FROM t_bus_order_list WHERE id = ?";
			OrderList orderList = OrderList.me().findFirst(sqlOrderList,orderListid);
			double refundAmount = orderList.getDouble("amount");
			//2.查询原订单总金额
			double orderAmount = order.getDouble("amount");
			//3.查询关联的所有的有效的退款单（状态为审核中、审核通过、已退款，因为审核不通过的可以忽略）的总金额
			String sqlAllRefund = "SELECT IFNULL(SUM(amount),0) amount FROM t_bus_order_refund WHERE state !=? AND orderNum = ?";
			OrderRefund orderRefund = OrderRefund.me().findFirst(sqlAllRefund,OrderCode.RefundState.VERIFY_FAILED,orderNum);
			double allRefrundAmount = orderRefund.getDouble("amount");
			//4.得出当前该订单可退款的总金额（防止double之间计算时出现无限小数情况，在此临时乘以100得出整数计算）
			double remainAmount = DoubleKit.sub(orderAmount,allRefrundAmount);
			//4.判断是否可退款
			if(remainAmount<=0 || refundAmount > remainAmount){
				flag = 4;
			}else{
				//4.1.插入零钱退款单
				String orderRefundNum = "T"+DatetimeKit.getFormatDate("yyyyMMddHHmmssSSS")+CommonKit.randomNum(3);
				if(!new OrderRefund()
						.set("refundNum", orderRefundNum)
						.set("type", OrderCode.RefundType.CANCEL_SINGLE)
						.set("orderNum", orderNum)
						.set("orderListid", orderListid)
						.set("amount", refundAmount)
						.save()){
					throw new Exception("生成退款单失败！");
				}
				//退款单生成成功
				flag = 5;
				//5.判断去除本次要退款金额后，如果已经没有剩余可退金额时，将订单状态变为“已取消”并记录订单变更日志
				if(remainAmount - refundAmount <= 0) {
					if(!order.set("orderState", OrderCode.OrderState.CANCEL).update()) {
						throw new Exception("更新订单状态失败！");
					}
					log(orderNum,OrderCode.OrderLogType.CANCEL,"配送员", OrderCode.OrderLogType.CANCEL_ACTION, "订单已取消");
					//退款单生成成功，但是订单金额已全部退还，所以将订单状态更新为“已取消”
					flag = 2;
				}
			}
		}
		return flag;
	}
	
	/**
	 * 零钱退款
	 * @param orderNum 订单号
	 * @param change 要退的零钱
	 * @return flag：-1：退款失败，1：退款成功，2：退款成功+订单已取消，3：剩余可退金额不足
	 */
	@Before(Tx.class)
	public int doChangeRefund(double change,String orderNum, Order order) throws Exception{
		int flag = -1;
		//1.查询原订单总金额
		double orderAmount = order.getDouble("amount");
		//2.查询关联的所有的有效的退款单（状态为审核中、审核通过、已退款，因为审核不通过的可以忽略）的总金额
		String sqlAllRefund = "SELECT IFNULL(SUM(amount),0) amount FROM t_bus_order_refund WHERE state !=? AND orderNum = ?";
		double allRefundAmount = 0;
		OrderRefund orderAllRefund = OrderRefund.me().findFirst(sqlAllRefund,OrderCode.RefundState.VERIFY_FAILED,orderNum);
		allRefundAmount = orderAllRefund.getDouble("amount");
		//3.得出当前该订单可退款的总金额（防止double之间计算时出现无限小数情况，在此临时乘以100得出整数计算）
		double remainAmount = DoubleKit.sub(orderAmount,allRefundAmount);
		//4.判断是否可退款
		if(remainAmount<=0 || change > remainAmount){
			flag = 3;
		}else{
			//4.1.插入零钱退款单
			String orderRefundNum = "T"+DatetimeKit.getFormatDate("yyyyMMddHHmmssSSS")+CommonKit.randomNum(3);
			if(!new OrderRefund()
					.set("refundNum", orderRefundNum)
					.set("type", OrderCode.RefundType.CHANGE_REFUND)
					.set("orderNum", orderNum)
					.set("amount", change)
					.save()){
				throw new Exception("生成退款单失败！");
			}
			//退款单生成成功
			flag = 4;
			//5.判断去除本次要退款金额后，如果已经没有剩余可退金额时，将订单状态变为“已取消”并记录订单变更日志
			if(remainAmount - change <= 0) {
				if(!order.set("orderState", OrderCode.OrderState.CANCEL).update()) {
					throw new Exception("更新订单状态失败！");
				}
				log(orderNum,OrderCode.OrderLogType.CANCEL,"配送员", OrderCode.OrderLogType.CANCEL_ACTION, "订单已取消");
				//退款单生成成功，但是订单金额已全部退还，所以将订单状态更新为“已取消”
				flag = 2;
			}
		}
		return flag;
	}
	
	/**
	 * 隐藏订单
	 * @param sellerid 当前登录配送员ID
	 * @param orderNum 订单号
	 */
	public boolean hideOrder(int sellerid, String orderNum) {
		return Db.update("UPDATE t_dict_store_seller_rel SET isShow = ? WHERE sellerid = ? AND orderNum = ?", SellerState.ShowState.HIDE, sellerid, orderNum)==1;
	}
	
	/**
	 * 获取订单当前退款中和已退款成功的金额（用来计算订单可退金额数量）
	 * @param orderNum 订单号
	 */
	public Record getOrderRefundAmount(String orderNum) {
		String sql = "SELECT"
				+ " bo.orderNum,bo.amount orderAmount,"
				+ " (SELECT IFNULL(SUM(bor1.amount),0) FROM t_bus_order_refund bor1 WHERE bor1.orderNum=? AND bor1.type=? AND bor1.state != ?) singleRefundAmount,"
				+ " (SELECT IFNULL(SUM(bor2.amount),0) FROM t_bus_order_refund bor2 WHERE bor2.orderNum=? AND bor2.type=? AND bor2.state != ?) changeRefundAmount"
				+ " FROM t_bus_order bo"
				+ " WHERE bo.orderNum = ?";
		return Db.findFirst(sql,
				orderNum,OrderCode.RefundType.CANCEL_SINGLE,OrderCode.RefundState.VERIFY_FAILED,
				orderNum,OrderCode.RefundType.CHANGE_REFUND,OrderCode.RefundState.VERIFY_FAILED,
				orderNum);
	}
	
	/**
	 * 查询订单各项退款金额，供页面展示
	 * @param order 订单对象
	 */
	public void getOrderRefundAmount(Order order){
		Record record = getOrderRefundAmount(order.getStr("orderNum"));
		if(record != null) {
			order.put("singleRefundAmount",record.getDouble("singleRefundAmount"));
			order.put("changeRefundAmount",record.getDouble("changeRefundAmount"));
		}
	}
}
